<?php
namespace App\Component\Wechat;

use EasyWeChat\Factory;
use GuzzleHttp\Client;
use GuzzleHttp\HandlerStack;
use Hyperf\Contract\ConfigInterface;
use Hyperf\Contract\ContainerInterface;
use Hyperf\Di\Annotation\Inject;
use Hyperf\Guzzle\HandlerStackFactory;
use Hyperf\Guzzle\RingPHP\CoroutineHandler;
use Overtrue\Socialite\Providers\AbstractProvider;
use Psr\SimpleCache\CacheInterface;

class WechatFactory {
    /**
     * @Inject()
     * @var ContainerInterface
     */
    protected $container;

    /**
     * @var Factory
     */
    private $miniProgram;

    /**
     * @var Factory
     */
    private $payment;

    public function __construct()
    {
        // 设置 OAuth 授权的 Guzzle 配置
        AbstractProvider::setGuzzleOptions([
            'http_errors' => false,
            'handler' => HandlerStack::create(new CoroutineHandler()),
        ]);
    }

    /**
     * @param $app \EasyWeChat\MiniProgram\Application|\EasyWeChat\Payment\Application
     */
    protected function init(&$app){
        // 设置 HttpClient，当前设置没有实际效果，在数据请求时会被 guzzle_handler 覆盖，但不保证 EasyWeChat 后面会修改这里。
        $config = $app['config']->get('http', []);
        $config['handler'] = $this->container->get(HandlerStackFactory::class)->create();
        $app->rebind('http_client', new Client($config));
        // 重写 Handler
        $app['guzzle_handler'] = $this->container->get(HandlerStackFactory::class)->create();
    }

    /**
     * @return \EasyWeChat\MiniProgram\Application
     */
    public function getMiniProgram()
    {
        if (!$this->miniProgram instanceof \EasyWeChat\MiniProgram\Application) {
            $app = Factory::miniProgram($this->container->get(ConfigInterface::class)->get('wechat.mini_program'));
            $this->init($app);
            $app['cache'] = $this->container->get(CacheInterface::class);
            $this->miniProgram = $app;
        }

        return $this->miniProgram;
    }

    /**
     * @return \EasyWeChat\Payment\Application
     */
    public function getPayment(){
        if (!$this->payment instanceof \EasyWeChat\Payment\Application) {
            $app = Factory::payment($this->container->get(ConfigInterface::class)->get('wechat.payment'));
            $this->init($app);
            $this->payment = $app;
        }

        return $this->payment;
    }
}